﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
using PathDelayFaultUniversalAnalyzer.Properties;
using TSU.FAMC.ComputerEngineering.Classes.Circuits.Readers;
using TSU.FAMC.ComputerEngineering.Classes.Diagnostics.PathDelayFaults;
using TSU.FAMC.ComputerEngineering.Classes.Enums;

namespace PathDelayFaultUniversalAnalyzer
{
    public partial class PathDelayFaultAnalyzerForm : Form
    {
        public PathDelayFaultAnalyzerForm()
        {
            InitializeComponent();
        }

        private void Button1Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            if (openFileDialog.FileNames.Length == 0)
            {
                MessageBox.Show(Resources.PathDelayFaultAnalyzerForm_Button1Click_Не_выбрано_ни_одного_файла_);
                return;
            }

            // reading files
            var results = new List<PdfResult>();
            foreach (var fileName in openFileDialog.FileNames)
            {
                var circuitName = Path.GetFileNameWithoutExtension(fileName);
                string fileStr;
                try
                {
                    // reading file
                    var streamReader = new StreamReader(fileName);
                    fileStr = streamReader.ReadToEnd();
                }
                catch (Exception ex)
                {
                    results.Add(new PdfResult { Name = circuitName, Status = PdfStatus.Error, Description = ex.Message});
                    continue;
                }

                // reading circuit
                var reader = new CircuitReaderPlain {Input = fileStr};

                try
                {
                    reader.Read();
                }
                catch (Exception ex)
                {
                    results.Add(new PdfResult { Name = circuitName, Status = PdfStatus.Error, Description = ex.Message });
                    continue;
                }

                // building tests
                var circuit = reader.Circuit.ExtractCombinationalEquivalent();
                List<PdfTest> tests;
                try
                {
                    tests = PathDelayFaultAnalyzer.BuildTest(reader.Circuit);
                }
                catch (Exception ex)
                {
                    results.Add(new PdfResult { Name = circuitName, Status = PdfStatus.Error, Description = ex.Message });
                    continue;
                }

                // collecting statistics
                var paths = circuit.CountPaths();
                var robustPaths = tests.Where(t => t.FaultType == PdfType.Robust).Count();
                var nonRobustPaths =
                    tests.Where(t => t.FaultType == PdfType.Nonrobust).GroupBy(t => t.PathString).Count();
                var falsePaths = tests.Where(t => t.FaultType == PdfType.False).Count();

                if (paths != robustPaths + nonRobustPaths + falsePaths)
                {
                    // something wrong
                    results.Add(new PdfResult
                    {
                        Name = circuitName,
                        Status = PdfStatus.Error,
                        Description = "Неверное число путей!",
                        Paths = paths,
                        RobustPaths = robustPaths,
                        NonRobustPaths = nonRobustPaths,
                        FalsePaths = falsePaths
                    });
                }

                results.Add(new PdfResult
                                {
                                    Name = circuitName,
                                    Status = PdfStatus.Success,
                                    Paths = paths,
                                    RobustPaths = robustPaths,
                                    NonRobustPaths = nonRobustPaths,
                                    FalsePaths = falsePaths
                                });
            }



            // writing results to excel

            // preparing excel worksheet
            var objExcel = new Microsoft.Office.Interop.Excel.Application();

            // excel workbook
            var objWorkBook = objExcel.Workbooks.Add(System.Reflection.Missing.Value);

            // excel worksheet
            var objWorkSheet = (Worksheet)objWorkBook.Sheets[1];

            // excel header
            objWorkSheet.Cells[2, 2] = "Название";
            objWorkSheet.Cells[2, 3] = "Путей";
            objWorkSheet.Cells[2, 4] = "Робастных путей";
            objWorkSheet.Cells[2, 5] = "Неробастных путей";
            objWorkSheet.Cells[2, 6] = "Ложных путей";
            objWorkSheet.Cells[2, 7] = "Статус";
            objWorkSheet.Cells[2, 8] = "Описание";

            for (var i = 0; i < results.Count; i++)
            {
                var result = results[i];
                objWorkSheet.Cells[3 + i, 2] = result.Name;
                objWorkSheet.Cells[3 + i, 3] = result.Paths;
                objWorkSheet.Cells[3 + i, 4] = result.RobustPaths;
                objWorkSheet.Cells[3 + i, 5] = result.NonRobustPaths;
                objWorkSheet.Cells[3 + i, 6] = result.FalsePaths;
                objWorkSheet.Cells[3 + i, 7] = result.Status == PdfStatus.Success ? "Ок" : "Ошибка";
                objWorkSheet.Cells[3 + i, 8] = result.Description;
            }

            // showing excel
            objExcel.Visible = true;
            objExcel.UserControl = true;
        }
    }
}
